package
{
	import com.lipi.excel.Excel;
	
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.events.Event;
	import flash.filesystem.File;
	import flash.system.ApplicationDomain;
	import flash.system.LoaderContext;
	import flash.utils.ByteArray;
	import flash.utils.Dictionary;
	
	import source.BitmapDataObj;
	import source.JsonObj;
	import source.OtherObj;
	import source.SwfObj;

	public class DataModelBasic
	{
		protected static var _instance:DataModelBasic;

		/**
		 * 取得DataModel单例的引用
		 */
		public static function getInstance():DataModelBasic
		{
			if (_instance == null)
			{
				_instance = new DataModelBasic();
			}
			return _instance;
		}

		public function DataModelBasic()
		{
			if (_instance != null)
			{
				throw new Error("Please use the method getInstance!");
			}
			else
			{
				init();
			}
		}

		/**
		 *	加载完成后的回调函数字典
		 */
		protected var _callbackFnDic:Dictionary;

		/**
		 *	json数据字典
		 */
		protected var _jsonDic:Dictionary;

		protected var _jsonList:Vector.<JsonObj>;

		/**
		 *	其它文件字典
		 */
		protected var _otherDic:Dictionary;

		protected var _otherList:Vector.<OtherObj>;

		/**
		 *	bitmapData数据字典
		 */
		protected var _bitmapDataDic:Dictionary;
		
		protected var _bitmapDataList:Vector.<BitmapDataObj>;
		
		/**
		 *	swf文件字典
		 */
		protected var _swfDic:Dictionary;


		protected var _swfList:Vector.<SwfObj>;

		/**
		 * 还未加载过的swf的File实例字典
		 */
		protected var _unLoadedFileDic:Dictionary;

		/**
		 *	添加一张excel配置表(xlsx格式)
		 * <BR/>(表格数据会被转化为json数据保存在DataModel.jsonList里)
		 * @param excelName 表名
		 * @param excel 表格数据
		 *
		 */
		public function addExcel(excelName:String, excel:Excel):void
		{
			var $jsonObj:JsonObj = JsonObj.parseData(excelName, excel);
			_jsonList.push($jsonObj);
			_jsonDic[excelName] = $jsonObj;
		}

		/**
		 *	添加一份Json配置
		 * <BR/>(数据会被转化为json数据保存在DataModel.jsonList里)
		 * @param fileName json文件名
		 * @param jsonStr Json字符串数据
		 *
		 */
		public function addJson(fileName:String, jsonStr:String):void
		{
			var $jsonObj:JsonObj = JsonObj.parseJsonData(fileName, jsonStr);
			_jsonList.push($jsonObj);
			_jsonDic[fileName] = $jsonObj;
		}

		/**
		 *	 添加位图数据
		 * @param fileName 文件名
		 * @param bitmapData 位图数据
		 * 
		 */
		public function addBitmapData(fileName:String,bitmapData:BitmapData):void
		{
			var $bitmapDataObj:BitmapDataObj = BitmapDataObj.parseData(fileName,bitmapData);
			_bitmapDataList.push($bitmapDataObj);
			_bitmapDataDic[fileName] = $bitmapDataObj;
		}
		
		/**
		 *	添加其它格式的文件
		 * @param fileName 文件名
		 * @param type 文件类型
		 * @param byteData 文件二进制数据
		 *
		 */
		public function addOther(fileName:String, type:String, byteData:ByteArray):void
		{
			var $otherObj:OtherObj = OtherObj.parseData(fileName, type, byteData);
			_otherList.push($otherObj);
			_otherDic[fileName] = $otherObj;
		}

		/**
		 *	添加一个待读取的swf文件
		 * @param swfName 素材文件名
		 * @param file swf的File文件实例
		 *
		 */
		public function addSwfFile(swfName:String, file:File):void
		{
			if (_swfDic[swfName] == null) //没有加载过的话
			{
				_unLoadedFileDic[swfName] = file;
			}
		}

		/**
		 *	通过配置表名获得对应配置文件数据强类型
		 * @param key 配置文件名
		 *
		 */
		public function getJsonObj(excelName:String):JsonObj
		{
			return _jsonDic[excelName];
		}

		/**
		 *	通过其它文件名获得对应其它文件数据强类型
		 * @param key 文件名
		 *
		 */
		public function getOtherObj(fileName:String):OtherObj
		{
			return _otherDic[fileName];
		}

		/**
		 *	通过文件名获取图像位图数据 
		 * @param fileName
		 * @return 
		 * 
		 */
		public function getBitmapDataObj(fileName:String):BitmapDataObj
		{
			return _bitmapDataDic[fileName];
		}
		
		/**
		 * 通过素材文件名获取swf文件数据强类型
		 * @param swfName 素材文件名
		 * @param callbackFn 加载完成后的回调函数 形式:fun(swf:SwfObj):void
		 * <BR/>[如果没有此素材文件名,则将向callbackFn参数中传入null]
		 */
		public function getSwfObj(swfName:String, callbackFn:Function):void
		{
			if (_swfDic[swfName] != null)
			{
				callbackFn(_swfDic[swfName]);
			}
			else
			{
				if (_unLoadedFileDic[swfName] != null)
				{
					_callbackFnDic[swfName] = callbackFn;
					var $file:File = _unLoadedFileDic[swfName];
					if ($file.exists)
					{
						$file.addEventListener(Event.COMPLETE, loadSwfComplete);
						$file.load();
					}
					else
					{
						callbackFn(null);
					}
				}
				else
				{
					callbackFn(null);
				}

			}

		}

		/**
		 *	json配置数据列表
		 */
		public function get jsonList():Vector.<JsonObj>
		{
			return _jsonList;
		}

		/**
		 *	其它文件列表
		 */
		public function get otherList():Vector.<OtherObj>
		{
			return _otherList;
		}

		/**
		 *	已加载过的swf文件数据列表
		 */
		public function get swfList():Vector.<SwfObj>
		{
			return _swfList;
		}

		/**
		 *	已加载过的bitmapData数据列表 
		 * @return 
		 * 
		 */
		public function get bitmapDataList():Vector.<BitmapDataObj>
		{
			return _bitmapDataList;
		}
		
		/**
		 *	添加一个swf文件数据
		 * @param swfName 文件名
		 * @param swfData 文件的ByteArray数据
		 *  @param appDomain 此swf对应的applicationDomain
		 */
		protected function addSwfData(swfName:String, swfData:ByteArray, appDomain:ApplicationDomain):void
		{
			var $swfObj:SwfObj = SwfObj.parseData(swfName, swfData, appDomain);
			_swfList.push($swfObj);
			_swfDic[swfName] = $swfObj;
		}


		protected function init():void
		{
			_jsonDic = new Dictionary();
			_swfDic = new Dictionary();
			_bitmapDataDic = new Dictionary();
			_otherDic = new Dictionary();
			_unLoadedFileDic = new Dictionary();
			_callbackFnDic = new Dictionary();
			_jsonList = new Vector.<JsonObj>;
			_swfList = new Vector.<SwfObj>;
			_bitmapDataList = new Vector.<BitmapDataObj>;
			_otherList = new Vector.<OtherObj>;
		}

		protected function loadSwfComplete(e:Event):void
		{
			var $file:File = e.target as File;
			var $swfName:String = $file.name.split(".")[0];
			var $callbackFn:Function = _callbackFnDic[$swfName];
			var $loader:Loader = new Loader();
			var $loaderContext:LoaderContext = new LoaderContext();
			$loaderContext.allowLoadBytesCodeExecution = true;
			$file.removeEventListener(Event.COMPLETE, loadSwfComplete);
			$loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadSwfAppDomainComplete);
			$loader.loadBytes($file.data, $loaderContext);

			function loadSwfAppDomainComplete(e:Event):void
			{
				$loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, loadSwfAppDomainComplete);

				addSwfData($swfName, $file.data, $loader.contentLoaderInfo.applicationDomain);
				delete _unLoadedFileDic[$swfName];
				delete _callbackFnDic[$swfName];

				$callbackFn(_swfDic[$swfName]);
			}
		}
	}
}
